/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.features.ruby_string;

import picounit.features.ruby_string.delayed.DefaultMethodInstructions;
import picounit.features.ruby_string.delayed.InsnInstruction;
import picounit.features.ruby_string.delayed.InvokeMethodInstruction;
import picounit.features.ruby_string.delayed.LdcInstruction;
import picounit.features.ruby_string.delayed.NamedVarInstruction;
import picounit.features.ruby_string.delayed.TypeInstruction;

public class RubyStringLdcInstruction extends DefaultMethodInstructions {
	public RubyStringLdcInstruction(String stringLiteral) {
		int openingBrace = stringLiteral.indexOf('{');
		int closingBrace = stringLiteral.indexOf('}', openingBrace + 1);

		if (openingBrace == -1 || closingBrace == -1) {
			add(new LdcInstruction(stringLiteral));

			return;
		}

		add(new TypeInstruction(NEW, "java/lang/StringBuffer"));
		add(new InsnInstruction(DUP));
		add(new InvokeMethodInstruction(INVOKESPECIAL, "java/lang/StringBuffer",
			"<init>", "()V"));

		int previousClosingBrace = -1;

		while (openingBrace != -1 && closingBrace != -1) {
			if (openingBrace > previousClosingBrace) {
				add(new LdcInstruction(stringLiteral.substring(previousClosingBrace+1, openingBrace)));
				add(new InvokeMethodInstruction(INVOKEVIRTUAL, "java/lang/StringBuffer",
					"append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"));

				add(new NamedVarInstruction(stringLiteral.substring(openingBrace+1, closingBrace)));
			}

			previousClosingBrace = closingBrace;

			openingBrace = stringLiteral.indexOf('{', closingBrace);
			closingBrace = stringLiteral.indexOf('}', openingBrace + 1);
		}

		add(new LdcInstruction(stringLiteral.substring(previousClosingBrace+1)));
		add(new InvokeMethodInstruction(INVOKEVIRTUAL, "java/lang/StringBuffer",
			"append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"));
		add(new InvokeMethodInstruction(INVOKEVIRTUAL, "java/lang/StringBuffer",
			"toString", "()Ljava/lang/String;"));
	}
}
